
package org.eteamcs.service.impl;

import java.util.List;

import org.acegisecurity.Authentication;
import org.acegisecurity.acl.basic.AclObjectIdentity;
import org.acegisecurity.acl.basic.BasicAclExtendedDao;
import org.acegisecurity.acl.basic.NamedEntityObjectIdentity;
import org.acegisecurity.acl.basic.SimpleAclEntry;
import org.acegisecurity.context.SecurityContextHolder;
import org.acegisecurity.userdetails.UserDetails;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eteamcs.dao.IContactDAO;
import org.eteamcs.model.Contact;
import org.eteamcs.model.ContactSearch;
import org.eteamcs.service.IContactManager;
import org.springframework.validation.Validator;


/**
 * Manager Implementation to table contacts
 * @author Paulo Neves
 * Generated by Javalee v. 1.1
 * $Id$
 */
public class ContactManager implements IContactManager {
    private Log log = LogFactory.getLog(ContactManager.class);
    private IContactDAO dao;
    private BasicAclExtendedDao basicAclExtendedDao;
    private Validator validator;

    public void setBasicAclExtendedDao(BasicAclExtendedDao basicAclExtendedDao) {
      this.basicAclExtendedDao = basicAclExtendedDao;
	  }
	
	  public BasicAclExtendedDao getBasicAclExtendedDao() {
	      return basicAclExtendedDao;
	  }
    
    public void setContactDAO(IContactDAO dao) {
        this.dao = dao;
    }

    public void setValidator(Validator validator) {
    	this.validator = validator;
    }
    
    public List getContacts(ContactSearch cs) {
        return dao.getContacts(cs);
    }
    
    public List getContactsByInitial(String initial) {
    	return dao.getContactsByInitial(initial);
    }
    
    public List getContactsByCompanyId(Long companyId) {
    	return dao.getContactsByCompanyId(companyId);
    }

    public Contact getContact(java.lang.Long contactId) {
        Contact contact = dao.getContact(contactId);

        if (contact == null) {
            log.warn("(contactId) '" + (contactId) + "' not found in database.");
        }

        return contact;
    }

    public Contact saveContact(Contact contact) {
        /*BindException errors = new BindException(contact, "contact");
        validator.validate(contact, errors);
        if (errors.hasErrors()) {
        	throw new RuntimeException("validation failed!", errors);
        }*/
    		
    	  boolean isNew = contact.getContactId()==null;
        dao.saveContact(contact);
        
        if(isNew) {
	        //      Grant the current principal access to the contact 
	        addPermission(contact, getUsername(),
	            new Integer(SimpleAclEntry.READ_WRITE_CREATE_DELETE));
	        addPermission(contact, "ROLE_SUPERVISOR",
	            new Integer(SimpleAclEntry.READ_WRITE_CREATE_DELETE));        
	        addPermission(contact, "ROLE_USER",
	            new Integer(SimpleAclEntry.READ));       
	
	        if (log.isDebugEnabled()) {
	            log.debug("Created contact " + contact
	                + " and granted admin permission to recipient " + getUsername());
	        }   
        }

        return contact;
    }

    public void addPermission(Contact contact, String recipient,
         Integer permission) {
         SimpleAclEntry simpleAclEntry = new SimpleAclEntry();
         simpleAclEntry.setAclObjectIdentity(makeObjectIdentity(contact));
         simpleAclEntry.setMask(permission.intValue());
         simpleAclEntry.setRecipient(recipient);
         basicAclExtendedDao.create(simpleAclEntry);

         if (log.isDebugEnabled()) {
             log.debug("Added permission " + permission + " for recipient "
                 + recipient + " contact " + contact);
         }
     }
    
    
    public void removeContact(java.lang.Long contactId) {
    	  Contact contact = dao.getContact(contactId);
        dao.removeContact(contactId);
        
        //  Delete the ACL information as well
        basicAclExtendedDao.delete(makeObjectIdentity(contact));

        if (log.isDebugEnabled()) {
            log.debug("Deleted contact " + contact
                + " including ACL permissions");
        }        
    }
    
	  protected String getUsername() {
	      Authentication auth = SecurityContextHolder.getContext()
	                                                 .getAuthentication();
	
	      if (auth.getPrincipal() instanceof UserDetails) {
	          return ((UserDetails) auth.getPrincipal()).getUsername();
	      } else {
	          return auth.getPrincipal().toString();
	      }
	  }

	  private AclObjectIdentity makeObjectIdentity(Contact contact) {
	      return new NamedEntityObjectIdentity(contact.getClass().getName(),
	          contact.getId().toString());
	  }    
	
}
